package log;


import javax.print.DocFlavor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// ios log format example
// 2019-05-20 20:02:48.943 Info|771|235576|QQPushMsgMonitor:485|pushMonitor||validatePushMsg begin

public class LogParserIOS extends LogParser
{
    private static Pattern _patternLineBegin = Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})\\.(\\d+) (\\w+)");

    @Override
    public void parse(String line) throws Exception {

        Matcher result = _patternLineBegin.matcher(line);
        if (result.find()) { // is new ling
            if(_parsingLogItem != null) {
                LogItem item = _parsingLogItem;
                _parsingLogItem = null;
                doOnLogItem(item);
            }
            _parsingLogItem = _parse(line);
            if (_parsingLogItem == null) {
                throw new Exception(String.format("failed to parse line '%s'", line));
            }
        }
        else {
            if (_parsingLogItem != null) {
                _parsingLogItem.content += "\n" + line;
            }
            else {
                throw new Exception(String.format("failed to parse line '%s'", line));
            }
        }
    }

    @Override
    public void flush() {

        LogItem item = _parsingLogItem;
        _parsingLogItem = null;
        if (item != null) {
            doOnLogItem(item);
        }
    }

    private static LogItem _parse(String line)
    {
        try {
            LogItem logItem = new LogItem();

            String[] fields = line.split("\\|", 7);
            if (fields.length != 7) {
                throw new Exception("invalid log format");
            }

            _parseDateTime(logItem, fields[0]);

            logItem.pid = Integer.parseInt(fields[1]);
            logItem.tid = Integer.parseInt(fields[2]);

            String[] srcFileLine = fields[3].split(":");
            if (srcFileLine.length > 0) {
                logItem.file = srcFileLine[0];
            }
            if (srcFileLine.length > 1) {
                logItem.lineNumber = Integer.parseInt(srcFileLine[1]);
            }

            logItem.tag = fields[4];
            logItem.module = fields[5];
            logItem.content = fields[6];

            return logItem;
        }
        catch (Exception e) {
            Logger.getGlobal().warning(String.format("failed to parse line, %s", line));
            return null;
        }
    }

    private static void _parseDateTime(final LogItem log, String field) throws Exception{

        String[] s = field.split(" ");
        if (s.length != 3) {
            throw new Exception("invalid date format");
        }

        try {
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
            // get date
            log.dateTime = s[0] + " " + s[1];
            // get time
            Date date = ft.parse(log.dateTime);
            log.time = date.getTime();
            // get tag
            log.level = s[2];
        }
        catch (Exception e) {
            throw new Exception("invalid date format");
        }
    }

    // 记录中间状态，一条日志可能会跨多行
    private LogItem _parsingLogItem;
}
